/**
    GpsNetwork lets you download files and log some system parameters from NetRs DGPS receivers.
    
    Copyright (C) 2009  Eduardo Maureira
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    email:emaureir@gmail.com
 */
package io;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Vector;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

/**
 * @author eduardo
 *
 */
public class JakartaFtpWrapper extends FTPClient {
	/** A convenience method for connecting and logging in */
	public boolean connectAndLogin (String host, String userName, String password)
			throws  IOException, UnknownHostException, FTPConnectionClosedException {
		boolean success = false;
		connect(host);
		int reply = getReplyCode();
		if (FTPReply.isPositiveCompletion(reply))
			success = login(userName, password);
		if (!success)
			disconnect();
		return success;
	}
	
	/** Turn passive transfer mode on or off. If Passive mode is active, a
	  * PASV command to be issued and interpreted before data transfers;
	  * otherwise, a PORT command will be used for data transfers. If you're
	  * unsure which one to use, you probably want Passive mode to be on. */
	public void setPassiveMode(boolean setPassive) {
		if (setPassive)
			enterLocalPassiveMode();
		else
			enterLocalActiveMode();
	}
	
	/** Use ASCII mode for file transfers */
	public boolean ascii () throws IOException {
		return setFileType(FTP.ASCII_FILE_TYPE);
	}
	
	/** Use Binary mode for file transfers */
	public boolean binary () throws IOException {
		return setFileType(FTP.BINARY_FILE_TYPE);
	}
	
	/** Download a file from the server, and save it to the specified local file */
	public boolean downloadFile (String serverFile, String localFile)
			throws IOException, FTPConnectionClosedException {
		FileOutputStream out = new FileOutputStream(localFile);
		boolean result = retrieveFile(serverFile, out);
		out.close();
		return result;
	}
	
	/** Upload a file to the server */
	public boolean uploadFile (String localFile, String serverFile) 
			throws IOException, FTPConnectionClosedException {
		FileInputStream in = new FileInputStream(localFile);
		boolean result = storeFile(serverFile, in);
		in.close();
		return result;
	}
	
	/** Get the list of files in the current directory as a Vector of Strings 
	  * (excludes subdirectories) */
	public Vector<String> listFileNames () 
			throws IOException, FTPConnectionClosedException {
		FTPFile[] files = listFiles();
		Vector<String> v;
		v = new Vector<String>();
		for (int i = 0; i < files.length; i++) {
			if (!files[i].isDirectory())
				v.addElement(files[i].getName());
		}
		return v;
	}
	
	/** Get the list of files in the current directory as a single Strings,
	  * delimited by \n (char '10') (excludes subdirectories) */
	public String listFileNamesString () 
			throws IOException, FTPConnectionClosedException {
		return vectorToString(listFileNames(), "\n");
	}
	
	/** Get the list of subdirectories in the current directory as a Vector of Strings 
	  * (excludes files) */
	public Vector<String> listSubdirNames () 
			throws IOException, FTPConnectionClosedException {
		FTPFile[] files = listFiles();
		Vector<String> v;
		v = new Vector<String>();
		for (int i = 0; i < files.length; i++) {
			if (files[i].isDirectory())
				v.addElement(files[i].getName());
		}
		return v;
	}
	
	/** Get the list of subdirectories in the current directory as a single Strings,
	  * delimited by \n (char '10') (excludes files) */
	public String listSubdirNamesString () 
			throws IOException, FTPConnectionClosedException {
		return vectorToString(listSubdirNames(), "\n");
	}
	
	/** Convert a Vector to a delimited String */
	private String vectorToString (Vector<String> v, String delim) {
		StringBuffer sb = new StringBuffer();
		String s = "";
		for (int i = 0; i < v.size(); i++) {
			sb.append(s).append((String)v.elementAt(i));
			s = delim;
		}
		return sb.toString();
	}
	
	public static void main (String[] args) {
		try {
			JakartaFtpWrapper ftp = new JakartaFtpWrapper();
			String serverName = "igscb.jpl.nasa.gov";
			if (ftp.connectAndLogin(serverName, "Anonymous", "me@whatever.com")) {
				System.out.println("Connected to " + serverName);
				try {
					System.out.println("Welcome message:\n" + ftp.getReplyString());
					ftp.changeWorkingDirectory("/pub/product/latest/ultra");
					System.out.println("Current Directory: " + ftp.printWorkingDirectory());
					ftp.setPassiveMode(true);
					System.out.println("Files in this directory:\n" + ftp.listFileNamesString());
					System.out.println("Subdirectories in this directory:\n" + ftp.listSubdirNamesString());
					System.out.println("Downloading file igu14782_18.sp3.Z");
					ftp.ascii();
					ftp.downloadFile("igu14782_18.sp3.Z", "/home/eduardo/igu14782_18.sp3.Z");
				} catch (Exception ftpe) {
					ftpe.printStackTrace();
				} finally {
					ftp.logout();
					ftp.disconnect();
				}
			} else {
				System.out.println("Unable to connect to" + serverName);
			}
			System.out.println("Finished");
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
		
}